﻿using log4net.Appender;
using log4net.Core;
using Newtonsoft.Json;
using RabbitMQ.Client;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Common.Logger.RabbitMQ
{
    public class RabbitMQAppender : AppenderSkeleton, IDisposable
    {
        RabbitMQProducer _producer;
        public RabbitMQSettings RabbitMQSettings { get; set; }
        protected override void OnClose()
        {
            base.OnClose();
            this.Dispose();
        }
        protected override void Append(LoggingEvent loggingEvent)
        {
            var message = GetMessage(loggingEvent);
            _producer?.ProduceAsync(new RabbitMQMessage { Message = message });
        }
        public override void ActivateOptions()
        {
            base.ActivateOptions();
            Init();
        }
        private string GetMessage(LoggingEvent loggingEvent)
        {
            using (var sr = new StringWriter())
            {
                Layout.Format(sr, loggingEvent);

                if (Layout.IgnoresException && loggingEvent.ExceptionObject != null)
                    sr.Write(loggingEvent.GetExceptionString());

                return sr.ToString();
            }
        }
        public void Dispose()
        {
            _producer?.Dispose();
            _producer = null;
        }
        void Init()
        {
            if (this.RabbitMQSettings == null)
            {
                throw new LogException("RabbitMQ setting is required");
            }
            if (string.IsNullOrEmpty(this.RabbitMQSettings.Host))
            {
                throw new LogException("RabbitMQ host is required");
            }
            if (string.IsNullOrEmpty(this.RabbitMQSettings.Queue))
            {
                throw new LogException("RabbitMQ queue name is required");
            }
            _producer = new RabbitMQProducer(this.RabbitMQSettings);
            _producer.Initialize();
        }
    }
    
}
